package com.net.test.utility;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

/**
 * 이놈은 스트럭쳐에서 사용하는 파일업로드 Spring에서 지원하는 파일업로드가 따로 있음
 * @author poo
 *
 */
@Service("fileManager")
public class FileManager {

	// path : 파일을 저장할 경로
	// 리턴 : 서버에 저장된 새로운 파일명
	public String doFileUpload(byte[] bytes, String originalFileName, String path) throws Exception {
		String newFileName = null;

		if(bytes == null)
			return null;
		
		// 클라이언트가 업로드한 파일의 이름
		if(originalFileName.equals(""))
			return null;
		
		// 확장자
		String fileExt = originalFileName.substring(originalFileName.lastIndexOf("."));
		if(fileExt == null || fileExt.equals(""))
			return null;
		
		// 서버에 저장할 새로운 파일명을 만든다.
		newFileName = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", 
				         Calendar.getInstance());
		newFileName += System.nanoTime();
		newFileName += fileExt;
		
		// 업로드할 경로가 존재하지 않는 경우 폴더를 생성 한다.
		File dir = new File(path);
		if(!dir.exists())
			dir.mkdirs();
		
		String fullpathname = path + File.separator + newFileName;
		FileOutputStream fos = new FileOutputStream(fullpathname);
		fos.write(bytes);
		fos.close();
		
		return newFileName;
	}
	
	
	// 파일 다운로드
	// saveFileName : 서버에 저장된 파일명
	// originalFileName : 클라이언트가 업로드한 파일명
	// path : 서버에 저장된 경로
	public boolean doFileDownload(String saveFileName, String originalFileName, String path, HttpServletResponse response) {
		String load_dir = path + File.separator + saveFileName;
		
        try {
    		if(originalFileName == null || originalFileName.equals(""))
    			originalFileName = saveFileName;
        	originalFileName = new String(originalFileName.getBytes("euc-kr"),"8859_1");
        } catch (UnsupportedEncodingException e) {
        }

	    try {
	        File file = new File(load_dir);

	        if (file.exists()){
	            byte readByte[] = new byte[4096];

	            response.setContentType("application/octet-stream");
				response.setHeader(
						"Content-disposition",
						"attachment;filename=" + originalFileName);

	            BufferedInputStream  fin  = new BufferedInputStream(new FileInputStream(file));
	            OutputStream outs = response.getOutputStream();
	            
	   			int read;
	    		while ((read = fin.read(readByte, 0, 4096)) != -1)
	    				outs.write(readByte, 0, read);
	    		outs.flush();
	    		outs.close();
	            fin.close();
	            
	            return true;
	        }
	    } catch(Exception e) {
	    }
	    
	    return false;
	}
	
	// 실제 파일 삭제
	public void doFileDelete(String fileName, String path) 
	        throws Exception {
		File file = null;
		String fullFileName = path + File.separator + fileName;
        file = new java.io.File(fullFileName);
        if (file.exists())
           file.delete();
	}	
	
	
	// 디렉토리 및 하위 파일 삭제
	public boolean deleteFolder(File targetFolder){
		
		if(targetFolder.isDirectory()){
		      File[] childFile = targetFolder.listFiles();
		      int size = childFile.length;
		      if (size > 0) {
		          for (int i = 0; i < size; i++) {
		              if (childFile[i].isFile()) {
		                  childFile[i].delete();
		              } else {
		                  deleteFolder(childFile[i]);
		              }
		          }
		      }
		      targetFolder.delete();
		      return (!targetFolder.exists());
		}else{
			return (targetFolder.exists());
		}
	 }
	
	// 파일생성.
	public String makeFile(String html, String path, String fileName){
			StringBuilder sb = new StringBuilder();
			BufferedWriter bufferedWriter=null;
			if(!new File(path).isDirectory()){
				File file = new File(path);
				file.mkdirs();
			}
				try {
					path  += File.separator+fileName;
					bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "utf-8"));
					bufferedWriter.write(html);
					bufferedWriter.flush();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					try {bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}
				}
		return sb.toString();
	}
	
	// 파일 이동
	public boolean moveFile(File in, File out){
		boolean flag=false;
		try {
			FileCopyUtils.copy(in, out);
			// 파일 카피후 원본 삭제.
			in.delete();
			flag=true;
		} catch (IOException e) {}
		return flag;
	}
	
	
	public boolean updateFile(String html, String path, String fileName){
		boolean flag=false;
		
		if(new File(path).isDirectory()){
			try {
				doFileDelete(fileName, path);
				makeFile(html, path, fileName);
				flag=true;
			} catch (Exception e) {}
		}
		return flag;
	}
	
	
	
	public MultipartFile getMultipartFile(HttpServletRequest requeset, String param){
		MultipartRequest mr = (MultipartRequest)requeset;
		MultipartFile file = mr.getFile(param);
		return file;
	}
	
	
	// 압축풀기
	@SuppressWarnings("rawtypes")
	public void unZip(String filePath, String dirPath) throws Exception {
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(filePath);
            Enumeration e = zipFile.entries();
            while( e.hasMoreElements() ) {
            	ZipEntry zipEntry=null;
                int startIndex = 0;
                int endIndex = 0;
                boolean isDirectory = false;
                String strEntry="";
            	try{
            		zipEntry = (ZipEntry)e.nextElement();
            		strEntry = zipEntry.getName();
            	}catch(IllegalArgumentException iae){
            		isDirectory = true;
            	}
                if( endIndex+1 == strEntry.length() || strEntry.indexOf(".") == -1) {isDirectory = true;}
                while(true) {
                    endIndex = strEntry.indexOf("/", startIndex);
                    if(endIndex != -1 ) {
                        String strDirectory = strEntry.substring(0, endIndex);
                        File fileDirectory = new File(dirPath+File.separator+strDirectory);

                        if( fileDirectory.exists() == false ) {
                            fileDirectory.mkdir();
                        }
                        startIndex = endIndex+1;
                    } else {
                        break;
                    }
                }

                if( isDirectory == false ) {
                    InputStream is = zipFile.getInputStream(zipFile.getEntry(strEntry));
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] byteBuffer = new byte[1024];
                    byte[] byteData = null;
                    FileOutputStream fos = null;
                    int nLength = 0;

                    while( (nLength=is.read(byteBuffer))>0 ) {
                        baos.write(byteBuffer, 0, nLength);
                    }
                    is.close();
                    byteData = baos.toByteArray();

                    fos = new FileOutputStream(dirPath+File.separator+strEntry);
                    fos.write(byteData);
                    fos.close();
                }
            }
        } catch(IOException e) {
            throw e;
        } finally {
            if( zipFile != null ) {
                try {
                    zipFile.close();
                    zipFile = null;
                } catch(Exception e) {}
            }
        }
    }
	
	
}

